#include "model.hpp"
#include "utility.hpp"
#include <fstream>
#include <iostream>

using namespace std;

int main() {
    Network n;
    n.addDevice("default");
    for (const string &name : {"atla", "chic", "hous", "kans", "losa", "newy32aoa", "salt", "seat", "wash"}) {
        n.addDevice(name);
        n.addLink(name, "default", "default", name + "-peer-default");
    }
    n.addLink("chic", "xe-0/1/0", "newy32aoa", "xe-0/1/3");
    n.addLink("chic", "xe-1/0/1", "kans", "xe-0/1/0");
    n.addLink("chic", "xe-1/1/3", "wash", "xe-6/3/0");
    n.addLink("hous", "xe-3/1/0", "losa", "ge-6/0/0");
    n.addLink("kans", "ge-6/0/0", "salt", "ge-6/1/0");
    n.addLink("chic", "xe-1/1/2", "atla", "xe-0/1/3");
    n.addLink("seat", "xe-0/0/0", "salt", "xe-0/1/1");
    n.addLink("chic", "xe-1/0/2", "kans", "xe-0/0/3");
    n.addLink("hous", "xe-1/1/0", "kans", "xe-1/0/0");
    n.addLink("seat", "xe-0/1/0", "losa", "xe-0/0/0");
    n.addLink("salt", "xe-0/0/1", "losa", "xe-0/1/3");
    n.addLink("seat", "xe-1/0/0", "salt", "xe-0/1/3");
    n.addLink("newy32aoa", "et-3/0/0-0", "wash", "et-3/0/0-0");
    n.addLink("newy32aoa", "et-3/0/0-1", "wash", "et-3/0/0-1");
    n.addLink("chic", "xe-1/1/1", "atla", "xe-0/0/0");
    n.addLink("losa", "xe-0/1/0", "seat", "xe-2/1/0");
    n.addLink("hous", "xe-0/1/0", "losa", "ge-6/1/0");
    n.addLink("atla", "xe-0/0/3", "wash", "xe-1/1/3");
    n.addLink("hous", "xe-3/1/0", "kans", "ge-6/2/0");
    n.addLink("atla", "ge-6/0/0", "hous", "xe-0/0/0");
    n.addLink("chic", "xe-1/0/3", "kans", "xe-1/0/3");
    n.addLink("losa", "xe-0/0/3", "salt", "xe-0/1/0");
    n.addLink("atla", "ge-6/1/0", "hous", "xe-1/0/0");
    n.addLink("atla", "xe-1/0/3", "wash", "xe-0/0/0");
    n.addLink("chic", "xe-2/1/3", "wash", "xe-0/1/3");
    n.addLink("atla", "xe-1/0/1", "wash", "xe-0/0/3");
    n.addLink("kans", "xe-0/1/1", "salt", "ge-6/0/0");
    n.addLink("chic", "xe-1/1/0", "newy32aoa", "xe-0/0/0");

    for (auto entry : n.nameToDevice) {
        if (entry.first == "default") continue;
        ifstream input("../dat/i2/" + entry.first + "apnotcomp");

        for (string lineStr; getline(input, lineStr);) {
            vector<string> tokens = split(lineStr, " ");
            if (tokens[0] == "fw") {
                string portName = split(tokens[3], ".")[0];
                Port *p = entry.second->getPortByName(portName);
                if (p == nullptr) {
                    cout << "Error: p shouldn't be null" << endl;
                }
                Rule *rule = new Rule {.device = entry.second, .dstIp = atol(tokens[1].c_str()), .priority = atoi(tokens[2].c_str()), .port = p};
                n.initialRules.push_back(rule);
            }
        }
    }

    test(n);
    return 0;
}